#ifndef _801AS_PTP_H__
#define _801AS_PTP_H__

#include "../../complib/libtsninsight/include/tsninsight.h"
#include "../../complib/libtsmp/include/tsmp_api.h"
#include "../../complib/cjson/cJSON.h"

#define DEBUG_BUFFER_MAX 4096
#define write_debug_msg(format, ...)                               \
    {                                                              \
        char buffer[DEBUG_BUFFER_MAX + 1] = {0};                   \
        snprintf(buffer, DEBUG_BUFFER_MAX, format, ##__VA_ARGS__); \
        FILE *fp = fopen("debug_log.txt", "a+");                   \
        if (fp != NULL)                                            \
        {                                                          \
            fwrite(buffer, strlen(buffer), 1, fp);                 \
        };                                                         \
        fclose(fp);                                                \
    }

#define LOG_ARGS __FILE__, __FUNCTION__, __LINE__

int sync_logger(const char *file, const char *function, int line, const char *fmt, ...);

#define SYNC_LOG(fmt, args...) sync_logger(LOG_ARGS, fmt, ##args);

int delay_logger(const char *file, const char *function, int line, const char *fmt, ...);

#define DELAY_LOG(fmt, args...) delay_logger(LOG_ARGS, fmt, ##args);

int offset_logger(const char *file, const char *function, int line, const char *fmt, ...);

#define OFFSET_LOG(fmt, args...) offset_logger(LOG_ARGS, fmt, ##args);

#define SYNC_CFG_PARA_FILE "./config/oss_cfg.json"
#define MAX_PORT_NUM 32 // 每个设备的最大端口数

/***************************************        时间同步寄存器（软件读写）           ******************************************/
#define CID_REG 0x00080001                         // OSS软件的MAC地址
#define GM_ROLE_REG 0x00080002                     // GM节点标志，位宽为1bit，1为有效
#define SYNC_PERIOD_REG 0x00080003                 // 时间同步周期，单位2^n ms，位宽4bit，最大支持32768ms的周期
#define OFFSET_THRESHOLD_REG 0x00080004            // 从时钟与主时钟的同步偏差阈值，位宽12bit
#define FCOR_H_CFG 0x00080006                      // 频率校正值寄存器，格式（8bit(ns)+41bit(2^-41ns)） 整数+部分小数
#define FCOR_L_CFG 0x00080007                      // 频率校正值寄存器，格式（8bit(ns)+41bit(2^-41ns)） 部分小数
#define STATE_REPORT_ENABLED_REG 0x00080008        // 链路延时测量和状态上报使能寄存器，位宽1bit，1为有效
#define PORT_PTP_ENABLED_REG 0x00080009            // 端口ptp使能，bitmap表示，1为有效，位宽32bit
#define MEASURE_PERIOD_REG 0x0008000A              // 链路延时测量周期，单位2^n ms，位宽4bit，最大支持32768ms的周期
#define MEASURE_RESPONDER_WAIT_TIME_REG 0x0008000B // 链路延时测量超时寄存器，单位2^n ms，位宽3bit，最大支持128ms的周期
#define MASTER_PORT_REG 0x0008000C                 // 同步主端口寄存器，bitmap表示，1表示主端口，0表示不为主端口，位宽32bit
#define CUMULATIVE_SCALED_RATE_OFFSET 0x0008000D   // cumulativeScaledRateOffset寄存器，位宽32bit
#define STEP_MODE 0x00080031                       // 同步模式寄存器，0代表两步模式，1代表1步模式，位宽32bit

#define SLAVE_PORT_P0_REG 0x40780000 // P0口的从端口标志寄存器，1表示从端口，0表示不为从端口
#define SLAVE_PORT_P1_REG 0x40B80000 // P1口的从端口标志寄存器，1表示从端口，0表示不为从端口
#define SLAVE_PORT_P2_REG 0x40F80000 // P2口的从端口标志寄存器，1表示从端口，0表示不为从端口
#define SLAVE_PORT_P3_REG 0x41380000 // P3口的从端口标志寄存器，1表示从端口，0表示不为从端口
#define SLAVE_PORT_P4_REG 0x41780000 // P4口的从端口标志寄存器，1表示从端口，0表示不为从端口
#define SLAVE_PORT_P5_REG 0x41B80000 // P5口的从端口标志寄存器，1表示从端口，0表示不为从端口
#define SLAVE_PORT_P6_REG 0x41F80000 // P6口的从端口标志寄存器，1表示从端口，0表示不为从端口
#define SLAVE_PORT_P7_REG 0x42380000 // P7口的从端口标志寄存器，1表示从端口，0表示不为从端口

#define SLAVE_PORT_P8_REG 0x42580000 // P8口的从端口标志寄存器，1表示从端口，0表示不为从端口

/***************************************        时间同步寄存器（软件只读）           ******************************************/
// 32个端口，寄存器范围为0x00080011~0x00080050
#define MEASURE_REQ_COUNT_BASE_REG 0x00080011  // 测量请求及请求超时计数器，用于存储每个端口发生测量请求的计数信息
#define MEASURE_RESP_COUNT_BASE_REG 0x00080012 // 测量响应及响应超时计数器，用于存储每个端口发生测量响应的计数信息

#define DELAY_STATE 0x00080032 // 测量状态寄存器
#define SYNC_STATE 0x000801B2  // 同步状态寄存器

// 寄存器对应的偏移量
#define FCOR_H_REG_OFFSET 0                  // 对应同步时钟频率校正值寄存器，占用14字节
#define CUMULATIVE_SCALED_RATE_REG_OFFSET 14 // 对应累计放大频差寄存器，占用10字节

// 寄存器对应的bit位，目前支持0~31
#define FCOR_H_REG_BIT 0                 // 对应同步时钟频率校正值寄存器
#define CUMULATIVE_SCALED_RATE_REG_BIT 1 // 对应累计放大频差寄存器

// 单个设备节点的配置信息
typedef struct
{
    u16 mid;               // 设备节点mid
    u8 gm_flag;            // GM节点标志gm_flag
    u32 master_port;       // master端口
    u32 slave_port;        // slave端口
    u32 port_ptp_enabled;  // 端口ptp使能
    u8 sync_period;        // 同步周期,单位ms
    u8 measure_period;     // 链路测量周期,单位ms
    u8 measure_timeout;    // 测量等待超时时间,单位ms
    u8 report_enable;      // 状态上报使能
    u16 offset_threshold;  // 时间同步偏差阈值,单位ns
    u8 tick_interval_flag; // 每拍长度标志
} node_cfg_para;

// 单个设备节点的同步信息
typedef struct
{
    u16 seq_num;          // 状态上报序列号
    u8 sync_flag;         // 节点当前时刻是否同步
    u16 sync_no_ok_count; // 时间偏差超过阈值的次数
    u16 offset;           // 与GM节点的时间偏差，单位ns
    int last_hop_cmRate;  // 上一跳节点的cumulativeScaledRateOffset值
    int cur_hop_cmRate;   // 当前节点的cumulativeScaledRateOffset值
    double RateRatio;     // 当前节点的RateRatio值
    double corr_fre;      // 修正后的频率值corr_fre,格式为（ 8bit(ns)+41bit(2-41ns)
} node_sync_state;

// 单个端口链路测量信息
typedef struct
{
    u16 seq_num;                // 状态上报序列号
    u16 delay;                  // 与上游节点的链路时延delay，单位ns
    u8 t1[10];                  // 本次测量时的t1值,格式为（ 48bit(s)+32bit(ns) )
    u8 t2[10];                  // 本次测量时的t2值,格式为（ 48bit(s)+32bit(ns) )
    u8 t3[10];                  // 本次测量时的t3值,格式为（ 48bit(s)+32bit(ns) )
    u8 t4[10];                  // 本次测量时的t4值,格式为（ 48bit(s)+32bit(ns) )
    u8 last_t3[10];             // 上次测量时的t3值,格式为（ 48bit(s)+32bit(ns) )
    u8 last_t4[10];             // 上次测量时的t4值,格式为（ 48bit(s)+32bit(ns) )
    u32 sub_t1_t4;              // t4-t1差值，单位为ns
    u32 sub_t2_t3;              // t3-t2差值，单位为ns
    u16 measure_req_count;      // 主动测量统计信息
    u16 measure_req_err_count;  // 主动测量出错统计信息
    u16 measure_resp_count;     // 被动测量统计信息
    u16 measure_resp_err_count; // 被动测量出错统计信息
    double neighbor_rate;       // 当前邻居频差比
    double max_neighbor_rate;   // 历史最大邻居频差比
} port_delay_state;

// 单个设备节点的链路测量信息
typedef struct
{
    port_delay_state *port_delay_info[MAX_PORT_NUM];
} node_delay_state;

// 单个设备节点的配置校验信息
typedef struct
{
    u8 buf[2048];
    u32 check_flag; // buf中的数据是否需校验的标志，bitmap形式，每一bit对应1项数据是否需要校验，1代表需校验，0代表不需校验
} node_check_info;

// 单个设备节点信息
typedef struct
{
    node_cfg_para cfg_para;       // 单个设备节点的配置信息
    node_sync_state sync_state;   // 单个设备节点的同步信息
    node_delay_state delay_state; // 单个设备节点的链路测量信息
    node_check_info check_info;   // 单个设备节点的配置校验信息
} node_info;

// 全网设备节点信息
typedef struct
{
    u16 gm_mid;                            // 主时钟节点的mid
    node_info *node_context[MAX_NODE_NUM]; // 设备节点信息
} net_node_context;

// 全网同步状态
typedef struct
{
    u16 max_offset; // 全网最大时间偏差
    u16 min_offset; // 全网最小时间偏差
} net_sync_state;

// 全网链路测量状态
typedef struct
{
    u16 max_delay; // 全网最大链路时延
    u16 min_delay; // 全网最小链路时延
} net_delay_state;

// 全网同步信息
typedef struct
{
    net_node_context context_info;    // 全网设备节点信息
    net_sync_state sync_state_info;   // 全网同步状态
    net_delay_state delay_state_info; // 全网链路测量状态
} sync_context;

typedef struct
{
    tsmp_header tsmp_head;
    tsmp_get_req_pkt_data get_req_head;
    u32 data[0];
} __attribute__((packed)) tsmp_get_req_pkt;

typedef struct
{
    u8 t1[10]; // 本次测量时的t1值,格式为（ 48bit(s)+32bit(ns) )
    u8 t2[10]; // 本次测量时的t2值,格式为（ 48bit(s)+32bit(ns) )
    u8 t3[10]; // 本次测量时的t3值,格式为（ 48bit(s)+32bit(ns) )
    u8 t4[10]; // 本次测量时的t4值,格式为（ 48bit(s)+32bit(ns) )
} __attribute__((packed)) osm_link_state_info;

int cfg_reg_value(u16 hcp_mid, u8 *pkt, u32 reg_data, u32 reg_addr);

int sync_init(u8 *network_interface);
int sync_para_cfg(u8 *network_interface, sync_context *sync_para_context, u8 *sync_para_cfg_file_name);
int sync_state_supervisor(sync_context *sync_para_context, opensync_reg_data *run_data, sync_state_table *state_table);
void sync_context_destory(sync_context *sync_contex_data);

#endif
